home *** CD-ROM | disk | FTP | other *** search
/ PC World Interactive 7 / PC World Interactive 7.iso / share / multimed / myflix_win32 / myflix_win32.exe / data1.cab / Libraries / tk8.0 / Safetk.tcl < prev    next >
Text File  |  1998-03-10  |  5KB  |  146 lines

  1. # safetk.tcl --
  2. #
  3. # Support procs to use Tk in safe interpreters.
  4. #
  5. # SCCS: @(#) safetk.tcl 1.6 97/08/13 16:08:18
  6. #
  7. # Copyright (c) 1997 Sun Microsystems, Inc.
  8. #
  9. # See the file "license.terms" for information on usage and redistribution
  10. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  
  12. # see safetk.n for documentation
  13.  
  14. #
  15. #
  16. # Note: It is UNSAFE to let any untrusted code being executed
  17. #       between the creation of the interp and the actual loading
  18. #       of Tk in that interp.
  19. #       You should "loadTk $slave" right after safe::tkInterpCreate
  20. #       Otherwise, if you are using an application with Tk
  21. #       and don't want safe slaves to have access to Tk, potentially
  22. #       in a malevolent way, you should use 
  23. #            ::safe::interpCreate -nostatics -accesspath {directories...}
  24. #       where the directory list does NOT contain any Tk dynamically
  25. #       loadable library
  26. #
  27.  
  28. # We use opt (optional arguments parsing)
  29. package require opt 0.1;
  30.  
  31. namespace eval ::safe {
  32.  
  33.     # counter for safe toplevels
  34.     variable tkSafeId 0;
  35.  
  36.     #
  37.     # tkInterpInit : prepare the slave interpreter for tk loading
  38.     #
  39.     # returns the slave name (tkInterpInit does)
  40.     #
  41.     proc ::safe::tkInterpInit {slave} {
  42.     global env tk_library
  43.     if {[info exists env(DISPLAY)]} {
  44.         $slave eval [list set env(DISPLAY) $env(DISPLAY)];
  45.     }
  46.     # there seems to be an obscure case where the tk_library
  47.     # variable value is changed to point to a sym link destination
  48.     # dir instead of the sym link itself, and thus where the $tk_library
  49.     # would then not be anymore one of the auto_path dir, so we use
  50.     # the addToAccessPath which adds if it's not already in instead
  51.     # of the more conventional findInAccessPath
  52.     ::interp eval $slave [list set tk_library [::safe::interpAddToAccessPath $slave $tk_library]]
  53.     return $slave;
  54.     }
  55.  
  56.  
  57. # tkInterpLoadTk : 
  58. # Do additional configuration as needed (calling tkInterpInit) 
  59. # and actually load Tk into the slave.
  60. # Either contained in the specified windowId (-use) or
  61. # creating a decorated toplevel for it.
  62.  
  63. # empty definition for auto_mkIndex
  64. proc ::safe::loadTk {} {}
  65.    
  66.     ::tcl::OptProc loadTk {
  67.     {slave -interp "name of the slave interpreter"}
  68.     {-use  -windowId {} "window Id to use (new toplevel otherwise)"}
  69.     } {
  70.     if {![::tcl::OptProcArgGiven "-use"]} {
  71.         # create a decorated toplevel
  72.         ::tcl::Lassign [tkTopLevel $slave] w use;
  73.         # set our delete hook (slave arg is added by interpDelete)
  74.         Set [DeleteHookName $slave] [list tkDelete {} $w];
  75.     }
  76.     tkInterpInit $slave;
  77.     ::interp eval $slave [list set argv [list "-use" $use]];
  78.     ::interp eval $slave [list set argc 2];
  79.     load {} Tk $slave
  80.     return $slave
  81.     }
  82.  
  83.     proc ::safe::tkDelete {W window slave} {
  84.     # we are going to be called for each widget... skip untill it's
  85.     # top level
  86.     Log $slave "Called tkDelete $W $window" NOTICE;
  87.     if {[::interp exists $slave]} {
  88.         if {[catch {::safe::interpDelete $slave} msg]} {
  89.         Log $slave "Deletion error : $msg";
  90.         }
  91.     }
  92.     if {[winfo exists $window]} {
  93.         Log $slave "Destroy toplevel $window" NOTICE;
  94.         destroy $window;
  95.     }
  96.     }
  97.  
  98. proc ::safe::tkTopLevel {slave} {
  99.     variable tkSafeId;
  100.     incr tkSafeId;
  101.     set w ".safe$tkSafeId";
  102.     if {[catch {toplevel $w -class SafeTk} msg]} {
  103.     return -code error "Unable to create toplevel for\
  104.         safe slave \"$slave\" ($msg)";
  105.     }
  106.     Log $slave "New toplevel $w" NOTICE
  107.  
  108.     set msg "Untrusted Tcl applet ($slave)"
  109.     wm title $w $msg;
  110.  
  111.     # Control frame
  112.     set wc $w.fc
  113.     frame $wc -bg red -borderwidth 3 -relief ridge ;
  114.  
  115.     # We will destroy the interp when the window is destroyed
  116.     bindtags $wc [concat Safe$wc [bindtags $wc]]
  117.     bind Safe$wc <Destroy> [list ::safe::tkDelete %W $w $slave];
  118.  
  119.     label $wc.l -text $msg \
  120.         -padx 2 -pady 0 -anchor w;
  121.  
  122.     # We want the button to be the last visible item
  123.     # (so be packed first) and at the right and not resizing horizontally
  124.  
  125.     # frame the button so it does not expand horizontally
  126.     # but still have the default background instead of red one from the parent
  127.     frame  $wc.fb -bd 0 ;
  128.     button $wc.fb.b -text "Delete" \
  129.         -bd 2  -padx 2 -pady 0 \
  130.         -command [list ::safe::tkDelete $w $w $slave]
  131.     pack $wc.fb.b -side right -fill both ;
  132.     pack $wc.fb -side right -fill both -expand 1;
  133.     pack $wc.l -side left  -fill both -expand 1;
  134.     pack $wc -side bottom -fill x ;
  135.  
  136.     # Container frame
  137.     frame $w.c -container 1;
  138.     pack $w.c -fill both -expand 1;
  139.     
  140.     # return both the toplevel window name and the id to use for embedding
  141.     list $w [winfo id $w.c] ;
  142. }
  143.  
  144. }
  145.